import { isUndef, isObject } from '../util/index'
import VNode from './vnode'
import { activeInstance } from '../instance/lifecycle'
const componentVNodeHooks = {
    init(vnode, hydrating) {
        if (
            vnode.componentInstance &&
            !vnode.componentInstance._isDestroyed &&
            vnode.data.keepAlive
        ) {
            //TODO
        } else {
            const child = vnode.componentInstance = createComponentInstanceForVnode(
                vnode,
                activeInstance
            )
            //组件调用集成vue$mount
            console.log('组件调用集成vue$mount并且获取到了vnode.componentInstance用于生成组件内部的元素')
            child.$mount(undefined, hydrating)
        }
    },
    prepatch (oldVnode, vnode) {

    },
    insert (vnode) {

    },
    destroy (vnode) {

    }
}
export function createComponentInstanceForVnode(vnode, parent) {
    const options = {
        _isComponent: true,
        _parentVnode: vnode,
        parent
    }
    const inlineTemplate = vnode.data.inlineTemplate
    //new 组件构造函数继承了vue原型上的方法
    console.log("new 组件构造函数继承了vue原型上的方法",options)
    return new vnode.componentOptions.Ctor(options)
}
export function createComponent(
    Ctor,
    data,
    context,
    children,
    tag
) {
    if (isUndef(Ctor)) {
        return
    }
    //拿到vue实例
    console.log("拿到vue实例",context.$options._base)
    const baseCtor = context.$options._base
    if (isObject(Ctor)) {
        //创建组件类
        console.log("创建组件类")
        Ctor = baseCtor.extend(Ctor)
    }
    if (typeof Ctor !== 'function') {
        return
    }
    let asyncFactory
    if (isUndef(Ctor.cid)) {
        asyncFactory = Ctor
        Ctor = resolveAsyncComponent(asyncFactory, baseCtor)
    };
    data = data || {};

    const propsData = '';

    const listeners = data.on
    //安装组件钩子
    installComponentHooks(data)
    console.log('安装组件钩子',data)
    const name = Ctor.options.name || tag
    const vnode = new VNode(
        `vue-component-${Ctor.cid}${name ? `-${name}` : ''}`,
        data, undefined, undefined, undefined, context,
        { Ctor, propsData, listeners, tag, children },
    )
    //创建组件vnode
    console.log('创建组件vnode',vnode)
    return vnode
}
const hooksToMerge = Object.keys(componentVNodeHooks)
function installComponentHooks (data) {
    const hooks = data.hook || (data.hook = {})
    for (let i = 0; i < hooksToMerge.length; i++) {
      const key = hooksToMerge[i]
      const existing = hooks[key]
      const toMerge = componentVNodeHooks[key]
      if (existing !== toMerge && !(existing && existing._merged)) {
        hooks[key] = toMerge
      }
    }
}